package com.lovely602.ai.alibaba.controller.structuredoutput;


import com.lovely602.ai.alibaba.entity.ActorsFilms;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.chat.prompt.PromptTemplate;
import org.springframework.ai.converter.BeanOutputConverter;
import org.springframework.ai.converter.ListOutputConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 *
 * @author lizhixing
 */
@Slf4j
@RestController
@RequestMapping(value = "/structuredoutput")
public class StructuredOutputController {

    @Autowired
    private ChatClient chatClient;

    @Autowired
    private ChatModel chatModel;

    /**
     * 结构化输出1
     */
    @RequestMapping(value = "/test1")
    public void test1(@RequestParam(value = "msg", defaultValue = "请将下面内容按照json格式返回", required = true) String msg) {
        ActorsFilms actorsFilms = chatClient.prompt()
                .user(u -> u.text("Generate the filmography of 5 movies for {actor}.")
                        .param("actor", "Tom Hanks"))
                .call()
                .entity(ActorsFilms.class);
        System.out.println(actorsFilms);
    }

    /**
     * 结构化输出2
     */
    @RequestMapping(value = "/test2")
    public void test2(@RequestParam(value = "msg", defaultValue = "请将下面内容按照json格式返回", required = true) String msg) {
        List<ActorsFilms> actorsFilms = chatClient.prompt()
                .user("Generate the filmography of 5 movies for Tom Hanks and Bill Murray.")
                .call()
                .entity(new ParameterizedTypeReference<List<ActorsFilms>>() {
                });
        System.out.println(actorsFilms);
    }

    /**
     * 结构化输出3
     */
    @RequestMapping(value = "/test3")
    public void test3(@RequestParam(value = "msg", defaultValue = "请将下面内容按照json格式返回", required = true) String msg) {
        Map<String, Object> result = ChatClient.create(chatModel).prompt()
                .user(u -> u.text("Provide me a List of {subject}")
                        .param("subject", "an array of numbers from 1 to 9 under their key name 'numbers'"))
                .call()
                .entity(new ParameterizedTypeReference<Map<String, Object>>() {
                });
        System.out.println(result);
    }

    /**
     * 结构化输出4
     */
    @RequestMapping(value = "/test4")
    public void test4(@RequestParam(value = "msg", defaultValue = "请将下面内容按照json格式返回", required = true) String msg) {
        List<String> flavors = ChatClient.create(chatModel).prompt()
                .user(u -> u.text("List five {subject}")
                        .param("subject", "ice cream flavors"))
                .call()
                .entity(new ListOutputConverter(new DefaultConversionService()));
        System.out.println(flavors);
    }

    /**
     * 结构化输出5
     */
    @RequestMapping(value = "/test5")
    public void test5(@RequestParam(value = "msg", defaultValue = "请将下面内容按照json格式返回", required = true) String msg) {

        BeanOutputConverter<ActorsFilms> beanOutputConverter = new BeanOutputConverter<>(ActorsFilms.class);

        String format = beanOutputConverter.getFormat();

        String actor = "Tom Hanks";

        String template = """
                Generate the filmography of 5 movies for {actor}.
                {format}
                """;

        PromptTemplate promptTemplate = new PromptTemplate(template);

        Prompt prompt = promptTemplate.create(Map.of("actor", actor, "format", format));

        String result = chatModel.call(prompt).getResult().getOutput().getText();
        if (StringUtils.isNotBlank(result)) {
            ActorsFilms actorsFilms = beanOutputConverter.convert(result);
            System.out.println(actorsFilms);
        }
        System.out.println();
    }


}
